package myJs.tool

import myJs.Implicits._
import myJs.myPkg._
import myJs.myPkg.jquery.{$, JQuery, JQueryAjaxSettings, JQueryXHR}
import org.scalajs.dom.{Blob, BlobPropertyBag, Element, Event, document}
import scalatags.Text.all._

import scala.collection.immutable.SeqMap
import scala.scalajs.js
import scala.scalajs.js.Dynamic.{global => g}
import scala.scalajs.js.JSON
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
import myJs.myPkg.bootstrap.Bootstrap.default._

/**
 * Created by yz on 2019/3/6
 */
@JSExportTopLevel("Tool")
object Tool extends ProjectTool with TableFilterTool {

  val confirmButtonClass = "btn-danger"
  val cancelButtonClass = "green"

  val pattern = "yyyy-mm-dd"
  val decDigits = 3

  def element(info: String) = {
    div(id := "content",
      span(id := "info", info,
        span(id := "progress", "")), " ",
      img(src := "/mtd/assets/images/running2.gif", width := 30, height := 20, cls := "runningImage")
    ).render
  }

  val zhInfo = "Info"
  val layerOptions = LayerOptions(title=zhInfo,closeBtn=0,skin="layui-layer-molv",btn=List())

  val wizardId = "wizard"

  def extractor(query: String) = {
    val result = js.RegExp("([^,]+)$").exec(query)
    if (result != null && result(1).isDefined) {
      result(1).toString.trim
    } else ""
  }

  def filterContentShow(y: Element, parentId: String) = {
    val parentJq=Tool.getParentJq(parentId)
    parentJq.find(s".filterContent").hide()
    val fieldName = Tool.getFilterDataFieldName(y)
    val contentJq = parentJq.find(s"#${fieldName}Content")
    val yTop = $(y).offset().top + $(y).height() + 2
    val pageWidth = document.body.clientWidth
    val yTotalLeft = $(y).offset().left
    val leftWidth = $("#myLeft").width()
    val yLeft = yTotalLeft - leftWidth
    val width = 210
    val trueYLeft = if (yTotalLeft + width > pageWidth) pageWidth - leftWidth - 220 - 6 else yLeft
    contentJq.css("top", yTop.toInt).css("left", trueYLeft.toInt).width(width)
    contentJq.show()
    Tool.filterContentFillBeforeValue(contentJq)
  }

  @JSExport("expand")
  def expand(y: Element) = {
    val tool = $(y).parent().find(".tools a:last")
    $(tool).click()
  }

  def refreshCheckboxView(map: SeqMap[String, String], tabId: String="") = {
    val parentJq=Tool.getParentJq(tabId)
    val html = map.map { case (v, showV) =>
      label(marginRight := 15,
        input(`type` := "checkbox", checked, value := v, onclick := s"Utils.setColumns('${v}','${tabId}')", showV)
      )
    }.mkString
    parentJq.find("#checkbox").html(html)
  }

  def getInputByName(name: String) = {
    $(s":input[name='${name}']")
  }

  def getParentElem(parentId: String) = {
    if (parentId.isEmpty) "body" else s"#${parentId}"
  }

  def getParentJq(parentId: String) = {
    val y = getParentElem(parentId)
    $(y)
  }

  def getInputByName(name: String, parentId: String) = {
    val parentElem = Tool.getParentElem(parentId)
    $(s"${parentElem}").findInputByName(name)
  }

  def getInputByValue(value: String) = {
    $(s":input[value='${value}']")
  }

  def getPercent(v: Double) = {
    (v * 100).toInt
  }

  def fillByName(rs: js.Dictionary[String], name: String, parentId: String = "") = {
    val valOp = rs.get(name)
    valOp.foreach { value =>
      val parentElem = Tool.getParentElem(parentId)
      val jq = $(parentElem).findInputByName(name)
      jq.`val`(value)
      if (jq.hasClass("myMinicolors")) {
        jq.minicolors("value", js.Dictionary("color" -> s"${jq.myVal}"))
      }
    }
  }

  @JSExport("fileInput")
  def fileInput = {
    val options = FileInputOptions.showPreview(false)
    $(".file").fileinput(options)
  }

  def fillByName(rs: js.Dictionary[String], name: String, parentJq: JQuery) = {
    val valOp = rs.get(name)
    valOp.foreach { value =>
      val jq = parentJq.findInputByName(name)
      jq.`val`(value)
      if (jq.hasClass("myMinicolors")) {
        jq.minicolors("value", js.Dictionary("color" -> s"${value}"))
      }
    }
  }

  def fillByNames(rs: js.Dictionary[String], names: Seq[String]) = {
    names.foreach { name =>
      fillByName(rs, name)
    }
  }

  def fillByNames(rs: js.Dictionary[String]) = {
    val names = $(".fillByName").mapElems { y =>
      $(y).attr("name").toString
    }.toArray
    names.foreach { name =>
      fillByName(rs, name)
    }
  }

  def onTabClick: js.Function = (e: Event, a: js.Any, index: Int) => {
    false
  }

  def checkedByNames(rs: js.Dictionary[String], names: Seq[String]) = {
    names.foreach { name =>
      checkedByName(rs, name)
    }
  }

  def checkedByName(rs: js.Dictionary[String], name: String) = {
    rs.get(name) match {
      case Some(value) => $(s":input[name='${name}']").attr("checked", true)
      case None => $(s":input[name='${name}']").attr("checked", false)
    }
  }

  def fillByNames(rs: js.Dictionary[String], formId: String) = {
    val names = $(s"#${formId} .fillByName").mapElems { y =>
      $(y).attr("name").toString
    }.toArray
    names.foreach { name =>
      fillByName(rs, name, formId)
    }
  }

  def fillByNames(rs: js.Dictionary[String], parentJq: JQuery) = {
    val names = parentJq.find(s".fillByName").mapElems { y =>
      $(y).attr("name").toString
    }.toArray
    names.foreach { name =>
      fillByName(rs, name, parentJq)
    }
  }

  def fillByIds(rs: js.Dictionary[String]) = {
    val ids = $(s".fillById").mapElems { y =>
      $(y).attr("id").toString
    }.toArray
    ids.foreach { name =>
      fillById(rs, name)
    }
  }

  def fillById(rs: js.Dictionary[String], id: String) = {
    val value = rs(id)
    $(s"#${id}").text(value)
  }

  def fillByNameAndTriggers(rs: JDJAn, names: List[String]): Unit = {
    names.foreach { name =>
      fillByNameAndTrigger(rs, name)
    }
  }

  def fillByNameAndTriggers(rs: JDJAn, parentId: String = ""): Unit = {
    val parentElem = Tool.getParentElem(parentId)
    val parentJq = $(s"${parentElem}")
    fillByNameAndTriggers(rs, parentJq)
  }

  def fillByNameAndTriggers(rs: JDJAn, parentJq: JQuery): Unit = {
    val names = parentJq.find(s".fillByNameAndTrigger").mapElems { y =>
      $(y).attr("name").toString
    }.toArray
    names.foreach { name =>
      fillByNameAndTrigger(rs, name, parentJq)
    }
  }

  def fillByNameAndTrigger(rs: JDJAn, name: String, parentId: String = ""): JQuery = {
    val parentElem = Tool.getParentElem(parentId)
    val parentJq = $(parentElem)
    fillByNameAndTrigger(rs, name, parentJq)
  }

  def fillByNameAndTrigger(rs: JDJAn, name: String, parentJq: JQuery): JQuery = {
    val jq = parentJq.findInputByName(name)
    val value = rs(name)
    if (jq.hasClass("myToggle")) {
      if (value == null || value == "None" || value.toString == "false") {
        jq.bootstrapToggle("off")
      } else {
        jq.bootstrapToggle("on")
      }
    } else {
      jq.`val`(value.toString).trigger("change")
    }

  }

  def refreshTable(data: js.Any, jq: JQuery, f: () => js.Any = () => ()) = {
    jq.bootstrapTable("load", data)
    f()
  }

  def bindEvt(parentId: String = "") = {
    val parentElem = Tool.getParentElem(parentId)
    val tableId = "table"
    val tableJq = $(s"${parentElem} #${tableId}")
    tableJq.on("check.bs.table", () => getIds(parentId)).on("uncheck.bs.table", () => getIds(parentId)).
      on("check-all.bs.table", () => getIds(parentId)).on("uncheck-all.bs.table", () => getIds(parentId)).
      on("page-change.bs.table", () => getIds(parentId))
  }

  def getIds(parentId: String = "") = {
    val ids = getIdsValue(parentId)
    val parentElem = Tool.getParentElem(parentId)
    if (ids.isEmpty) {
      $(s"${parentElem} .idsButton").attr("disabled", true)
    } else {
      $(s"${parentElem} .idsButton").attr("disabled", false)
    }
  }

  def getIdsValue(parentId: String = "") = {
    val parentElem = Tool.getParentElem(parentId)
    val arrays = $(s"${parentElem} #table").bootstrapTable("getSelections").toJArJDJAn
    arrays.map { x =>
      x("id").toString
    }.toList
  }

  def popover = {
    val options = js.Dictionary("container" -> "body", "trigger" -> "hover")
    $(".selfQuestion").popover(options)
  }

  def downloadXlsx(fileName: String, arrays: List[List[String]]) = {
    val worksheet = Xlsx.utils.aoa_to_sheet(arrays)
    val workbook = Xlsx.utils.book_new()
    Xlsx.utils.book_append_sheet(workbook, worksheet)
    val wbout = Xlsx.write(
      workbook,
      WriteOptions(
        bookType = "xlsx",
        bookSST = true,
        `type` = "array"
      )
    )
    FileSaver.saveAs(
      new Blob(
        js.Array(wbout),
        new BlobPropertyBag {
          `type` = "application/octet-stream"
        }
      ),
      fileName
    )
  }

  def dbFmt(v: String) = {
    if (v.isDouble) {
      ujson.Num(v.toDouble)
    } else {
      ujson.Str(v)
    }
  }


}
